// Problem: 
// Contest: 
// URL: 
// Memory Limit: 
// Time Limit: 
// #pragma GCC optimize("Ofast")
// #pragma GCC optimize("unroll-loops")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
	while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
	return s*w;
}
struct node
{
	int i,j,num;
};
bool cmp(node x,node y)
{
	return x.num<y.num;
}
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int n,m,mx=0;
vector<vector<int>> dp,a;
vector<node> d;
signed main()
{
	cin>>n>>m;
	int c=1;
	a=dp=vector<vector<int>>(n+1,vector<int>(m+1,1));
	d=vector<node>(n*m+1);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			cin>>a[i][j];
			d[c].num=a[i][j];
			d[c].i=i,d[c].j=j;
			c++;
		}
	sort(d.begin()+1,d.end(),cmp);
	for(int i=1;i<=n*m;i++)
	{
		for(int k=0;k<4;k++)
		{
			int x=dx[k]+d[i].i,y=dy[k]+d[i].j;
			if(x>0&&y>0&&x<=n&&y<=m&&d[i].num>a[x][y])
			{
				dp[d[i].i][d[i].j]=max(dp[d[i].i][d[i].j],dp[x][y]+1);
			}
		}
		mx=max(dp[d[i].i][d[i].j],mx);
	}
	cout<<mx;
	return 0;
}
